home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Texteditors / Origami / Sources / src / origami / getmsg.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  6.6 KB  |  275 lines

  1. /*{{{}}}*/
  2. /*{{{  #includes*/
  3. #ifdef CONFIG_H
  4. #   include "config.h"
  5. #endif
  6.  
  7. #ifdef VARARGS
  8. #  include <varargs.h>
  9. #else
  10. #  include <stdarg.h>
  11. #endif
  12. #include <sys/types.h>
  13. #include <errno.h>
  14. #include <fcntl.h>
  15. #include <limits.h>
  16. #include <string.h>
  17. #include <unistd.h>
  18. #include <stdio.h>
  19.  
  20. #define GETMSG_C
  21. #define I_MESSAGES_C
  22. #define I_SCREEN_C
  23.  
  24. #include "origami.h"
  25. #include <h/envvar_str.h>
  26. #include <lib/ori_add_lib.h>
  27. /*}}}  */
  28.  
  29. /*{{{  variable declarations*/
  30. public unsigned char **rc_msg=0;
  31. public int rc_msg_count=0;
  32. public int msg_file= -1;
  33. public msgtyp last_message = M_BASE_FORMAT;
  34. /*}}}  */
  35.  
  36. /*{{{  i_to_ua*/
  37. public unsigned char *i_to_ua(int x)
  38. {
  39. # define NBSIZE ((sizeof(int)<<2)+1)
  40.   static unsigned char number[NBSIZE];
  41.   unsigned char *s;
  42.   boolean neg;
  43.  
  44.   if ((neg=(x<0))) x= -x;
  45.   s=number+NBSIZE-1;
  46.   *s=0;
  47.   do
  48.    { *(--s)=hex_digits[x%10]; }
  49.   while ((x/=10)>0);
  50.   if (neg) *(--s)='-';
  51.   return(s);
  52. }
  53. /*}}}  */
  54. /*{{{  get and format a message*/
  55. #ifdef VARARGS
  56.    public unsigned char *get_msg(n,va_alist) msgtyp n; va_dcl
  57. #else
  58.    public unsigned char *get_msg(msgtyp n, ... )
  59. #endif
  60. {
  61.   /*{{{  variable declarations*/
  62.   va_list ap;
  63. #  define MAX_MSG_LEN (1024+BIND_NAME_LEN*NO_OCL_CMD_OPTS+3*_POSIX_PATH_MAX)
  64. #  define GETMSGLEN ((LINELEN>=MAX_MSG_LEN)?(LINELEN+1):MAX_MSG_LEN)
  65.   static unsigned char s[GETMSGLEN+1];
  66.   unsigned char *x;
  67.   unsigned char *y;
  68.   unsigned char *z;
  69.   /*{{{  buffer for read msg-entries*/
  70.   /*{{{  type MSGBUFF*/
  71.   typedef struct
  72.    { unsigned int time;
  73.      msgtyp n;
  74.      unsigned char str[MSG_LENGTH+2];
  75.    } MSGBUFF;
  76.   /*}}}  */
  77. #  define MSG_START_TIME ((unsigned int) ~0)
  78.   static MSGBUFF msg_buff[]=
  79.    /*{{{  empty init. end of list is M_BASE_FORMAT*/
  80.    { { MSG_START_TIME, NUM_MESSAGES, "" },
  81.      { MSG_START_TIME, NUM_MESSAGES, "" },
  82.      { MSG_START_TIME, NUM_MESSAGES, "" },
  83.      { MSG_START_TIME, NUM_MESSAGES, "" },
  84.      { MSG_START_TIME, NUM_MESSAGES, "" },
  85.      { MSG_START_TIME, NUM_MESSAGES, "" },
  86.      { MSG_START_TIME, NUM_MESSAGES, "" },
  87.      { MSG_START_TIME, M_BASE_FORMAT, "\0" BASENAMEF }
  88.    };
  89.    /*}}}  */
  90.   static unsigned int msg_time=MSG_START_TIME;
  91.   /*}}}  */
  92.   /*}}}  */
  93.  
  94.   ocl_msg("get msg %d",n);
  95.   /*{{{  start arglist handling*/
  96. #  ifdef VARARGS
  97.      va_start(ap);
  98. #  else
  99.      va_start(ap,n);
  100. #  endif
  101.   /*}}}  */
  102.   /*{{{  x=format string*/
  103.   if (n==MSG_ARG_FORMAT)
  104.      x=va_arg(ap,unsigned char*);
  105.   else
  106.    /*{{{  set x to msg-string from file*/
  107.    { unsigned int t = --msg_time;
  108.      int i = 0;
  109.      MSGBUFF *b = msg_buff;
  110.  
  111.      last_message=n;
  112.      /*{{{  search in list*/
  113.      while (b->n!=n && b->n!=M_BASE_FORMAT)
  114.       { if (b->time>t)
  115.          { t=b->time;
  116.            i=b-msg_buff;
  117.          }
  118.         b++;
  119.       }
  120.      /*}}}  */
  121.      if (b->n==n)
  122.       /*{{{  found, so set time to now*/
  123.       { b->time=msg_time;
  124.         x=b->str+1;
  125.       }
  126.       /*}}}  */
  127.      else
  128.       /*{{{  read msg from file to buffer*/
  129.       { ori_assert(msg_file>=0,"msg-file");
  130.         b=msg_buff+i;
  131.         if
  132.           /*{{{  seek or read not ok?*/
  133.           (   (  lseek(msg_file,
  134.                         (off_t)((n-1)*(MSG_LENGTH+MSG_ADDITIONAL)),
  135.                         SEEK_SET)
  136.                  ==(off_t)-1
  137.                 )
  138.            || (read(msg_file,(char *)b->str+1,(size_t)MSG_LENGTH)==-1)
  139.            || !b->str[1]
  140.           )
  141.           /*}}}  */
  142.             x=(unsigned char*)M_MIS_MES;
  143.          else
  144.           /*{{{  prepare read string for buffer*/
  145.           {
  146.             /*{{{  cut trailing spaces*/
  147.             x=x=b->str+MSG_LENGTH;
  148.             while (*--x==' ');
  149.             *(x+1)='\0';
  150.             x=b->str+1;
  151.             if (!*x)
  152.                x=(unsigned char*)one_space;
  153.             /*}}}  */
  154.             b->time=msg_time;
  155.             b->n=n;
  156.            }
  157.           /*}}}  */
  158.       }
  159.       /*}}}  */
  160.      /*{{{  maybe shift time, if 0 reached*/
  161.      if (!msg_time)
  162.       { for (b=msg_buff;b->n!=M_BASE_FORMAT;(b++)->time=MSG_START_TIME);
  163.         msg_time=MSG_START_TIME;
  164.       }
  165.      /*}}}  */
  166.    }
  167.    /*}}}  */
  168.   /*}}}  */
  169.   for (y=s;;)
  170.    /*{{{  handle one char/format in msg*/
  171.    { ori_assert(y<=(s+GETMSGLEN),"msg-length");
  172.      switch ((*y = *x++))
  173.       {
  174.         /*{{{  0 -> end string*/
  175.         case '\0':
  176.            break;
  177.         /*}}}  */
  178.         /*{{{  % - only %s, %c, %o, %x and %d implemented*/
  179.         case '%':
  180.          {
  181. #          define BUFF_SIZE (4+3*sizeof(int))
  182.            unsigned char buff[BUFF_SIZE];
  183.            unsigned int modul;
  184.  
  185.            switch (*x++)
  186.             {
  187.               /*{{{  get string*/
  188.               case 's':
  189.                  z=va_arg(ap,unsigned char*);
  190.                  break;
  191.               /*}}}  */
  192.               /*{{{  get char-string*/
  193.               case 'c':
  194.                  buff[0]=(unsigned char)va_arg(ap,int);
  195.                  if (buff[0]=='\0')
  196.                     goto end_string;
  197.                  if (buff[0]<' ')
  198.                   { buff[1]=ctrl_decode[buff[0]];
  199.                     buff[0]=CTRL_MARK;
  200.                     buff[2]='\0';
  201.                   }
  202.                  else
  203.                     buff[1]='\0';
  204.                  z=buff;
  205.                  break;
  206.               /*}}}  */
  207.               /*{{{  get hex-string*/
  208.               case 'x':
  209.                  modul=16;
  210.                  goto decode_ox;
  211.               /*}}}  */
  212.               /*{{{  get octal-string*/
  213.               case 'o':
  214.                  modul=8;
  215.                  goto decode_ox;
  216.               /*}}}  */
  217.               /*{{{  get int-string*/
  218.               case 'd':
  219.                  modul=10;
  220.                  goto decode_ox;
  221.               /*}}}  */
  222.               /*{{{  decode %o or %x*/
  223.               decode_ox:
  224.                { unsigned int d;
  225.  
  226.                  z=buff+BUFF_SIZE-1;
  227.                  d=va_arg(ap,unsigned int);
  228.                  *z='\0';
  229.                  do
  230.                   { *--z=hex_digits[d%modul];
  231.                     d=d/modul;
  232.                   }
  233.                  while (d);
  234.                  break;
  235.                }
  236.               /*}}}  */
  237.               /*{{{  empty string*/
  238.               default:
  239.                  continue;
  240.               /*}}}  */
  241.             }
  242.            while (*z)
  243.               *y++ = *z++;
  244.            continue;
  245.          }
  246.         /*}}}  */
  247.         /*{{{  \ - only \n,\\ implemented*/
  248.         case '\\':
  249.          { switch ((*y = *x++))
  250.             { case 'n':
  251.                  *y='\n';
  252.               default:
  253.                  y++;
  254.                  break;
  255.             }
  256.            continue;
  257.          }
  258.         /*}}}  */
  259.         /*{{{  default*/
  260.         default:
  261.            y++;
  262.            continue;
  263.         /*}}}  */
  264.       }
  265.      break;
  266.    }
  267.    /*}}}  */
  268. end_string:
  269.   *y='\0';
  270.   va_end(ap);
  271.   ocl_msg((char*)s,0);
  272.   return s;
  273. }
  274. /*}}}  */
  275.